﻿using BigEgg.Framework.UnitTesting;
using FMStudio.Documents.TemplateDocument.Models;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BigEgg.Framework.Foundation;
using FMStudio.Documents.TemplateDocument.Properties;
using System.IO;
using System.Xml.Linq;

namespace FMStudio.Documents.TemplateDocument.Test.Models
{
    [TestClass]
    public class TemplateInformationTest
    {
        [TestMethod]
        public void GeneralTemplateInformationTest()
        {
            TemplateInformation templateInformation = new TemplateInformation("NewTemplate");

            Assert.AreEqual("NewTemplate", templateInformation.Name);
            Assert.AreEqual("NewTemplate", templateInformation.Description);
            Assert.AreEqual("", templateInformation.Icon);
            Assert.AreEqual(1, templateInformation.SortOrder);
            Assert.AreEqual("NewTemplate", templateInformation.Description);
            Assert.IsTrue(templateInformation.ProvideDefaultName);
            Assert.AreEqual("1.0", templateInformation.RequiredVersion);
            Assert.AreEqual(0, templateInformation.NumberOfParentCategoriesToRollUp);
            Assert.IsTrue(templateInformation.EnableLocationField);
            Assert.IsTrue(templateInformation.EnableLocationBrowser);

            templateInformation.Icon = Path.Combine(Environment.CurrentDirectory, "icon.ico");
            Assert.AreEqual("", templateInformation.Validate());

            TemplateInformation templateInformation2 = new TemplateInformation();
            Assert.AreEqual("", templateInformation2.Name);
            Assert.AreEqual("", templateInformation2.Description);
        }

        [TestMethod]
        public void PropertiesWithNotification()
        {
            TemplateInformation templateInformation = new TemplateInformation();

            AssertHelper.PropertyChangedEvent(templateInformation, x => x.Name, () => templateInformation.Name = "Name");
            Assert.AreEqual("Name", templateInformation.Name);

            AssertHelper.PropertyChangedEvent(templateInformation, x => x.Description, () => templateInformation.Description = "Description");
            Assert.AreEqual("Description", templateInformation.Description);

            AssertHelper.PropertyChangedEvent(templateInformation, x => x.Icon, () => templateInformation.Icon = "Icon");
            Assert.AreEqual("Icon", templateInformation.Icon);

            AssertHelper.PropertyChangedEvent(templateInformation, x => x.SortOrder, () => templateInformation.SortOrder = 10);
            Assert.AreEqual(10, templateInformation.SortOrder);

            AssertHelper.PropertyChangedEvent(templateInformation, x => x.DefaultName, () => templateInformation.DefaultName = "NewProject");
            Assert.AreEqual("NewProject", templateInformation.DefaultName);

            AssertHelper.PropertyChangedEvent(templateInformation, x => x.ProvideDefaultName, () => templateInformation.ProvideDefaultName = false);
            Assert.AreEqual(false, templateInformation.ProvideDefaultName);

            AssertHelper.PropertyChangedEvent(templateInformation, x => x.RequiredVersion, () => templateInformation.RequiredVersion = "1.1");
            Assert.AreEqual("1.1", templateInformation.RequiredVersion);

            AssertHelper.PropertyChangedEvent(templateInformation, x => x.NumberOfParentCategoriesToRollUp, () => templateInformation.NumberOfParentCategoriesToRollUp = 1);
            Assert.AreEqual(1, templateInformation.NumberOfParentCategoriesToRollUp);

            AssertHelper.PropertyChangedEvent(templateInformation, x => x.EnableLocationField, () => templateInformation.EnableLocationField = false);
            Assert.AreEqual(false, templateInformation.EnableLocationField);

            AssertHelper.PropertyChangedEvent(templateInformation, x => x.EnableLocationBrowser, () => templateInformation.EnableLocationBrowser = false);
            Assert.AreEqual(false, templateInformation.EnableLocationBrowser);
        }

        [TestMethod]
        public void NameValidationTest()
        {
            TemplateInformation templateInformation = new TemplateInformation("NewTemplate");
            Assert.AreEqual("", templateInformation.Validate("Name"));

            templateInformation.Name = null;
            Assert.AreEqual(Resources.TemplateInformationNameMandatory, templateInformation.Validate("Name"));

            templateInformation.Name = "";
            Assert.AreEqual(Resources.TemplateInformationNameMandatory, templateInformation.Validate("Name"));
        }

        [TestMethod]
        public void DescriptionValidationTest()
        {
            TemplateInformation templateInformation = new TemplateInformation("NewTemplate");
            Assert.AreEqual("", templateInformation.Validate("Description"));

            templateInformation.Description = null;
            Assert.AreEqual(Resources.TemplateInformationDescriptionMandatory, templateInformation.Validate("Description"));

            templateInformation.Description = "";
            Assert.AreEqual("", templateInformation.Validate("Description"));
        }

        [TestMethod]
        public void IconValidationTest()
        {
            TemplateInformation templateInformation = new TemplateInformation("NewTemplate");
            Assert.AreEqual(Resources.TemplateInformationIconMandatory, templateInformation.Validate("Icon"));

            templateInformation.Icon = "abc:\"\\test.test";
            Assert.AreEqual(Resources.TemplateInformationIconPathRooted, templateInformation.Validate("Icon"));

            templateInformation.Icon = Path.Combine(Environment.CurrentDirectory, "test.test");
            Assert.AreEqual("", templateInformation.Validate("Icon"));
        }

        [TestMethod]
        public void SortOrderValidationTest()
        {
            TemplateInformation templateInformation = new TemplateInformation("NewTemplate");
            Assert.AreEqual("", templateInformation.Validate("SortOrder"));

            templateInformation.SortOrder = 0;
            Assert.AreEqual(
                string.Format(Resources.TemplateInformationSortOrderRange, null, 1, 65536),
                templateInformation.Validate("SortOrder"));

            templateInformation.SortOrder = 65537;
            Assert.AreEqual(
                string.Format(Resources.TemplateInformationSortOrderRange, null, 1, 65536),
                templateInformation.Validate("SortOrder"));

            templateInformation.SortOrder = 65536;
            Assert.AreEqual("", templateInformation.Validate("SortOrder"));

            templateInformation.SortOrder = 1000;
            Assert.AreEqual("", templateInformation.Validate("SortOrder"));
        }

        [TestMethod]
        public void DefaultNameValidationTest()
        {
            TemplateInformation templateInformation = new TemplateInformation("NewTemplate");
            Assert.AreEqual("", templateInformation.Validate("DefaultName"));

            templateInformation.DefaultName = "";
            Assert.AreEqual(Resources.TemplateInformationDefaultNameMandatory, templateInformation.Validate("DefaultName"));

            templateInformation.DefaultName = null;
            Assert.AreEqual(Resources.TemplateInformationDefaultNameMandatory, templateInformation.Validate("DefaultName"));

            templateInformation.ProvideDefaultName = false;
            Assert.AreEqual("", templateInformation.Validate("DefaultName"));
        }

        [TestMethod]
        public void RequiredVersionValidationTest()
        {
            TemplateInformation templateInformation = new TemplateInformation("NewTemplate");
            Assert.AreEqual("", templateInformation.Validate("RequiredVersion"));

            templateInformation.RequiredVersion = "";
            Assert.AreEqual(Resources.TemplateInformationRequiredVersionMandatory, templateInformation.Validate("RequiredVersion"));

            templateInformation.RequiredVersion = null;
            Assert.AreEqual(Resources.TemplateInformationRequiredVersionMandatory, templateInformation.Validate("RequiredVersion"));
        }

        [TestMethod]
        public void NumberOfParentCategoriesToRollUpValidationTest()
        {
            TemplateInformation templateInformation = new TemplateInformation("NewTemplate");
            Assert.AreEqual("", templateInformation.Validate("NumberOfParentCategoriesToRollUp"));

            templateInformation.NumberOfParentCategoriesToRollUp = -1;
            Assert.AreEqual(
                string.Format(Resources.TemplateInformationNumberOfParentCategoriesToRollUpGreaterThan, null, 0, 255), 
                templateInformation.Validate("NumberOfParentCategoriesToRollUp"));

            templateInformation.NumberOfParentCategoriesToRollUp = 256;
            Assert.AreEqual(
                string.Format(Resources.TemplateInformationNumberOfParentCategoriesToRollUpGreaterThan, null, 0, 255),
                templateInformation.Validate("NumberOfParentCategoriesToRollUp"));

            templateInformation.NumberOfParentCategoriesToRollUp = 255;
            Assert.AreEqual("", templateInformation.Validate("NumberOfParentCategoriesToRollUp"));

            templateInformation.NumberOfParentCategoriesToRollUp = 0;
            Assert.AreEqual("", templateInformation.Validate("NumberOfParentCategoriesToRollUp"));
        }

        [TestMethod]
        public void SerializationTest()
        {
            TemplateInformation templateInformation = new TemplateInformation("NewTemplate");
            templateInformation.Description = "";
            templateInformation.Icon = Path.Combine(Environment.CurrentDirectory, "icon.ico");

            XElement element = templateInformation.ObjectToXElement();
            Assert.IsNotNull(element.Element("Description"));
            TemplateInformation newTemplateInformation = element.XElementToObject<TemplateInformation>();

            Assert.AreEqual(newTemplateInformation.Name, templateInformation.Name);
            Assert.AreEqual(newTemplateInformation.Description, templateInformation.Description);
            Assert.AreEqual(newTemplateInformation.Icon, templateInformation.Icon);
            Assert.AreEqual(newTemplateInformation.SortOrder, templateInformation.SortOrder);
            Assert.AreEqual(newTemplateInformation.Description, templateInformation.Description);
            Assert.IsTrue(newTemplateInformation.ProvideDefaultName);
            Assert.AreEqual(newTemplateInformation.RequiredVersion, templateInformation.RequiredVersion);
            Assert.AreEqual(newTemplateInformation.NumberOfParentCategoriesToRollUp, templateInformation.NumberOfParentCategoriesToRollUp);
            Assert.IsTrue(newTemplateInformation.EnableLocationField);
            Assert.IsTrue(newTemplateInformation.EnableLocationBrowser);
        }
    }
}
